package com.source.multithread.mutilProductorAndConsumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author wengqy
 * @Date 2020/12/19
 */
public class ProductorAndConsumer {
    public static void main(String[] args) {

        SynContainer synContainer = new SynContainer();
        Productor productor1 = new Productor(synContainer);
        Productor productor2 = new Productor(synContainer);
        Productor productor3 = new Productor(synContainer);
        Productor productor4 = new Productor(synContainer);

        Consumer consumer1 = new Consumer(synContainer);
        Consumer consumer2 = new Consumer(synContainer);
        Consumer consumer3 = new Consumer(synContainer);
        Consumer consumer4 = new Consumer(synContainer);

        new Thread(productor1).start();
        new Thread(productor2).start();
        new Thread(productor3).start();
        new Thread(productor4).start();

        new Thread(consumer1).start();
        new Thread(consumer2).start();
        new Thread(consumer3).start();
        new Thread(consumer4).start();


    }
}

class Productor implements Runnable {
    SynContainer synContainer;

    public Productor(SynContainer synContainer) {
        this.synContainer = synContainer;
    }


    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            synContainer.push(new Chicken(i));
            System.out.println(Thread.currentThread().getName() + "生产了，第  " + i + " 只鸡");
        }
    }

}

class Consumer implements Runnable {

    SynContainer synContainer;

    public Consumer(SynContainer synContainer) {
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "消费了，第  " + synContainer.pop().id + " 只鸡");
        }
    }
}

class Chicken {
    int id;

    public Chicken(int id) {
        this.id = id;
    }

}

class SynContainer {
/*
    final Lock lock = new ReentrantLock();
    final Condition notFull = lock.newCondition();
    final Condition notEmpty = lock.newCondition();*/

    //  Chicken chickens[] = new Chicken[10];
    Chicken chickens[] = new Chicken[10];
    int count = 0;
     final Lock lock = new ReentrantLock();
    final  Condition pro=  lock.newCondition();
    final  Condition con=  lock.newCondition();

    public   void push(Chicken chicken) {

        try{
            lock.lock();
            while (chickens.length == count) {   // 当多个生产者和消费者时，要将if 改为 while !important *********
                // 缓冲区放满了,生产者等待，通知消费者去消费
                try {
                   // this.wait();
                     pro.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 缓冲区没有满 ，继续生产鸡
            chickens[count] = chicken;
            count++;
            // 通知消费者 消费
            con.signal();
        //    con.signal();
        }finally {
            lock.unlock();
        }

    }

    public   Chicken pop() {
       try {
           lock.lock();
           while (count == 0) { // 当多个生产者和消费者时，要将if 改为 while  ******************************
               // 缓冲区没了，消费者等待， 生产者等待
               try {
                   con.await();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
           // 取出鸡，消费
           count--;
           Chicken chicken1 = chickens[count];
           // 通知生产者生产
         //  lock.notifyAll();
           pro.signal();
           return chicken1;
       }finally {
           lock.unlock();
       }
    }

/*

    public synchronized void push(Chicken chicken) {
        while (chickens.length == count) {   // 当多个生产者和消费者时，要将if 改为 while !important *********
            // 缓冲区放满了,生产者等待，通知消费者去消费
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 缓冲区没有满 ，继续生产鸡
        chickens[count] = chicken;
        count++;
        // 通知消费者 消费
        this.notifyAll();
    }

    public synchronized Chicken pop() {
        while (count == 0) { // 当多个生产者和消费者时，要将if 改为 while  ******************************
            // 缓冲区没了，消费者等待， 生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 取出鸡，消费
        count--;
        Chicken chicken1 = chickens[count];
        // 通知生产者生产
        this.notifyAll();
        return chicken1;
    }

*/




}